package com.htbb.base.util;

import java.util.HashMap;
import java.util.Map;

import javax.crypto.spec.SecretKeySpec;

import org.apache.log4j.Logger;

import com.htbb.base.cache.CacheService;
import com.htbb.model.User;



public class Token {
	
	public static final String CACHE_TYPE = "token";
	
	private static final Logger LOGGER = Logger.getLogger(Token.class);
	

	public static String KEY = "token"; 
	
	private static HashMap<String, Object> token_list = new HashMap<String, Object>();


	private static void saveTokenString(String tokenStr, Map<String, Object> map, CacheService cacheService) {
		if (cacheService != null) {
			cacheService.set(CACHE_TYPE, tokenStr, map);
		} else if(cacheService == null ){
			token_list.put(tokenStr, map);			
		}
    }
	public static boolean updateToken(String tokenStr, Map<String, Object> map, CacheService cacheService) {
		boolean removeToken = Token.removeToken(tokenStr, cacheService);
		if(removeToken){
			saveTokenString(tokenStr, map, cacheService);
			return true;
		}
		return false;
	}

	public static String generateTokenString(Long custAid) {
		String timeNow = String.valueOf(System.currentTimeMillis());
		String params = custAid + "|" + timeNow;
		SecretKeySpec secretKeySpec;
		byte[] decrypt = null;
		try {
			secretKeySpec = SecurityUtils.getSecretKeySpec(KEY.getBytes());
			decrypt = SecurityUtils.encrypt(params.getBytes(), secretKeySpec);
		} catch (Exception e) {
			LOGGER.error("AES 加密失败");
		}
		String key = SecurityUtils.parseByte2HexStr(decrypt);
		return key;
	}

	/**
	 * Generate a token string, and save the string in session, then return the
	 * token string.
	 * 
	 * @param HttpSession
	 *            session
	 * @return a token string used for enforcing a single request for a
	 *         particular transaction.
	 */
	public static String getTokenString(Map<String, Object> map, CacheService cacheService) {
		String tokenStr = generateTokenString(((User)map.get("user")).getUserId());
		saveTokenString(tokenStr, map, cacheService);
		return tokenStr;
	}

	/**
	 * check whether token string is valid. if session contains the token
	 * string, return true. otherwise, return false.
	 * 
	 * @param String
	 *            tokenStr
	 * @param HttpSession
	 *            session
	 * @return true: session contains tokenStr; false: session is null or
	 *         tokenStr is id not in session
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> isTokenStringValid(String tokenStr, CacheService cacheService) {
		Map<String, Object> map = null;
		if (cacheService != null && cacheService.isConnected()) {
			map = (Map<String, Object>)cacheService.get(CACHE_TYPE, tokenStr);
		} else if (token_list.containsKey(tokenStr)) {
			map = (Map<String, Object>)token_list.get(tokenStr);
		}
		return map;
	}
	
	public static boolean removeToken(String tokenStr, CacheService cacheService) {
		if (cacheService != null) {
			cacheService.delete(CACHE_TYPE, tokenStr);
		}
		if (token_list.containsKey(tokenStr)) {
			token_list.remove(tokenStr);
		}
		return true;
	}
	
	public static int countActiveUsers() {
		return token_list.size();
	}
	
	
}